﻿using System;
using System.Net;
using System.Collections.Generic;
using SCG.General;

namespace SCG.SolarVengeanceEngine.Orders
{
    //Transport order contains a list of transport sources, and a single destination
    public class TransportOrder : MapObjectOrder
    {
        //constructors        
        public TransportOrder(SVGame game, OrderType ot, SVMapObject svm)
            : base(game, ot, svm)
        {               
        }
        public TransportOrder(SVGame game, OrderType ot, SVTokenizer tok)
            : base(game, ot, tok)
        {
            int num = tok.TokenInt;
            _nextSource = tok.TokenInt;
            while (num > 0)
            {
                _sources.Add(tok.TokenMapObject);
                num--;
            }
            MovingToDestination = tok.TokenBoolean;
        }

        //The list of sources
        public List<SVMapObject> Sources
        {
            get
            {
                return _sources;
            }
        }

        //The next source that the starship should visit
        public SVMapObject NextStop
        {
            get
            {
                if (MovingToDestination)
                    return MapObject;
                else
                    return _sources[_nextSource];
            }
        }

        //Return the last source in the route
        public SVMapObject LastSource
        {
            get
            {
                return Sources[Sources.Count - 1];
            }
        }

        //Is the freighter coming to the destination
        public bool MovingToDestination { get; set; }

        //Check the validity of the next source
        public bool IsSourceValid(SVMapObject svm, Player p)
        {
            if (svm is StarSystem)
            {
                StarSystem sys = svm as StarSystem;
                return sys.Owner == p;
            }
            else
            {
                StarShip ship = svm as StarShip;
                if (ship.Destroyed)
                    return false;
                else
                    return ship.Owner == p;
            }
        }

        //Advance to the next source in the chain
        public void Advance()
        {
            if (MovingToDestination)
            {
                MovingToDestination = false;
                _nextSource = 0;
            }            
            else if (NextStop == LastSource)
            {             
                MovingToDestination = true;
            }
            else
            {          
                _nextSource++;
            }
        }

        //Remove a source
        public void RemoveSource(SVMapObject svm)
        {
            if (Sources.Contains(svm))
                Sources.Remove(svm);
        }

        //persistence
        public override string Persist()
        {
            SVTokenizer tok = new SVTokenizer(Game);
            tok.AppendToken(Sources.Count);
            tok.AppendToken(_nextSource);
            foreach (SVMapObject svm in Sources)
                tok.AppendToken(svm);
            tok.AppendToken(MovingToDestination);
            return base.Persist() + tok.Result;
        }

        //string representation
        public override string ToString()
        {
            string s = "Transport to ";
            if (MapObject is StarSystem)
                s += StarSystem.Name;
            else
                s += StarShip.ShipType + " " + StarShip.Code;
            return s;
        }

        //update target point
        public override SCGPoint TargetPoint
        {
            get
            {
                return NextStop.Location;
            }
        }

        //does it target a starship?
        public override bool OrderTargetsStarShip
        {
            get
            {
                return NextStop is StarShip;
            }
        }
        public override StarShip StarShipTargeted
        {
            get
            {
                return NextStop as StarShip;
            }
        }

        //private members
        private int _nextSource = 0;
        private List<SVMapObject> _sources = new List<SVMapObject>();
    }
}
